{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#  Convolutional Neural Network\n",
    "\n",
    "### Convolutional Layers: [512,512] ; Dense Layers [512] \n",
    "\n",
    "CNN is trained on raw data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Get the data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Stored variables and their in-db values:\n",
      "X_test              -> defaultdict(<class 'list'>, {0: array([[[  6.37165\n",
      "X_train             -> array([[[-0.00462901, -0.00327594,  0.00218376, ..\n",
      "snrs                -> [-20, -18, -16, -14, -12, -10, -8, -6, -4, -2, 0, \n",
      "y_test              -> defaultdict(<class 'list'>, {0: array([7, 1, 3, ..\n",
      "y_train             -> array([2, 4, 7, ..., 6, 4, 5])\n"
     ]
    }
   ],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from collections import defaultdict\n",
    "from time import time\n",
    "\n",
    "%store -r\n",
    "%store"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training data:  (80000, 2, 128) and labels:  (80000,)\n",
      "\n",
      "Test data:\n",
      "Total 20 (4000, 2, 128) arrays for SNR values:\n",
      "[-20, -18, -16, -14, -12, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18]\n"
     ]
    }
   ],
   "source": [
    "print(\"Training data: \", X_train.shape, \"and labels: \", y_train.shape)\n",
    "print()\n",
    "print(\"Test data:\")\n",
    "print(\"Total\", len(X_test), X_test[18].shape, \"arrays for SNR values:\")\n",
    "print(sorted(X_test.keys()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Standardize the features"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training set (80000, 2, 128)\n",
      "Test set corresponding to one snr value (4000, 2, 128)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "sc = StandardScaler()\n",
    "_X_train = np.reshape(X_train, [X_train.shape[0], X_train.shape[1]*X_train.shape[2]])\n",
    "_X_train = sc.fit_transform(_X_train)\n",
    "\n",
    "X_train = np.reshape(_X_train, X_train.shape)\n",
    "print(\"Training set\", X_train.shape)\n",
    "\n",
    "_X_test = defaultdict(list)\n",
    "for snr in snrs:\n",
    "    _X_test[snr] = np.reshape(X_test[snr], [X_test[snr].shape[0], X_test[snr].shape[1]*X_test[snr].shape[2]])\n",
    "    _X_test[snr] = sc.transform(_X_test[snr])\n",
    "    X_test[snr] = np.reshape(_X_test[snr], X_test[snr].shape)\n",
    "    \n",
    "print(\"Test set corresponding to one snr value\", X_test[18].shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Design and train the CNN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 0 training accuracy : 0.2490234375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0.1\n",
      "Epoch 1 training accuracy : 0.34375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0.1\n",
      "Epoch 2 training accuracy : 0.3720703125\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0.1\n",
      "Epoch 3 training accuracy : 0.4306640625\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0.1\n",
      "Epoch 4 training accuracy : 0.4404296875\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0.1\n",
      "Epoch 5 training accuracy : 0.4794921875\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0.1\n",
      "Epoch 6 training accuracy : 0.45703125\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0.1\n",
      "Epoch 7 training accuracy : 0.4716796875\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0.1\n",
      "Epoch 8 training accuracy : 0.51171875\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0.1\n",
      "Epoch 9 training accuracy : 0.5556640625\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0.1\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0.1\n",
      "Training took 157.154333 minutes\n"
     ]
    }
   ],
   "source": [
    "height = 2\n",
    "width = 128\n",
    "channels = 1\n",
    "n_features = height * width\n",
    "\n",
    "feature_map1 = 512\n",
    "ksize_conv1 = 2\n",
    "stride_conv1 = 1\n",
    "\n",
    "feature_map2 = 512\n",
    "ksize_conv2 = ksize_conv1\n",
    "stride_conv2 = stride_conv1\n",
    "\n",
    "pool_layer_maps2 = feature_map2\n",
    "\n",
    "n_fully_conn1 = 512\n",
    "\n",
    "n_classes = 8\n",
    "  \n",
    "X = tf.placeholder(tf.float32, shape=[None, height, width])\n",
    "X_reshaped = tf.reshape(X, shape=[-1, height, width, channels])\n",
    "labels = tf.placeholder(tf.int32, shape=[None])\n",
    "training_ = tf.placeholder_with_default(False, shape=[])\n",
    "\n",
    "xavier_init = tf.contrib.layers.xavier_initializer()\n",
    "relu_act = tf.nn.relu\n",
    "\n",
    "# ------------------ Convolutional and pooling layers ----------------------------\n",
    "\n",
    "def convolutional_layer(X, filter_, ksize, kernel_init, strides, padding):\n",
    "    convolutional_layer = tf.layers.conv2d(X, filters = filter_, kernel_initializer = kernel_init,\n",
    "                                           kernel_size = ksize, strides = strides,\n",
    "                                          padding = padding, activation = relu_act)\n",
    "    return convolutional_layer\n",
    "\n",
    "def pool_layer(convlayer, ksize, strides, padding, pool_maps):\n",
    "    pool = tf.nn.max_pool(convlayer, ksize, strides, padding)\n",
    "    dim1, dim2 = int(pool.get_shape()[1]), int(pool.get_shape()[2])\n",
    "    pool_flat = tf.reshape(pool, shape = [-1, pool_maps * dim1 * dim2])\n",
    "    return pool_flat\n",
    "\n",
    "conv_layer1 = convolutional_layer(X_reshaped, feature_map1, ksize_conv1, xavier_init, stride_conv1, padding = \"SAME\")\n",
    "\n",
    "conv_layer2 = convolutional_layer(conv_layer1, feature_map2, ksize_conv2, xavier_init, stride_conv2, padding = \"SAME\")\n",
    "\n",
    "pool_layer2_flat = pool_layer(conv_layer2, [1,2,2,1], [1,2,2,1], \"VALID\", pool_layer_maps2)\n",
    "\n",
    "# ----------------- Fully connected and dropout layers -------------------\n",
    "\n",
    "def dense_layer(input_layer, n_neurons, kernel_init, activation):\n",
    "    fully_conn = tf.layers.dense(inputs = input_layer, units = n_neurons, activation = activation,\n",
    "                                kernel_initializer = kernel_init)\n",
    "    return fully_conn\n",
    "        \n",
    "dense_layer1 = dense_layer(pool_layer2_flat, n_fully_conn1, xavier_init, relu_act)\n",
    "\n",
    "# ----------------- Output softmax layer ---------------------------\n",
    "\n",
    "logits = tf.layers.dense(dense_layer1, n_classes)\n",
    "softmax_activations = tf.nn.softmax(logits)\n",
    "\n",
    "# ----------------- Specify performance measure -------------------------------\n",
    "\n",
    "cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits = logits, labels = labels)\n",
    "loss = tf.reduce_mean(cross_entropy)\n",
    "optimizer = tf.train.AdamOptimizer()\n",
    "train_operation = optimizer.minimize(loss)\n",
    "\n",
    "correct_predictions = tf.nn.in_top_k(logits, labels, 1)\n",
    "accuracy = tf.reduce_mean(tf.cast(correct_predictions, tf.float32))\n",
    "\n",
    "# ---------------- Execution phase -------------------------------------------\n",
    "    \n",
    "n_epochs = 10\n",
    "batch_size = 1024\n",
    "n_train = X_train.shape[0]\n",
    "n_iter = n_train//batch_size\n",
    "\n",
    "acc_test = defaultdict(list)\n",
    "\n",
    "path = \"./CNN_2conv_1dense.0.1\"  \n",
    "saver = tf.train.Saver()\n",
    "\n",
    "start = time()\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    tf.global_variables_initializer().run()\n",
    "    for epoch in range(n_epochs):\n",
    "        for iteration in range(n_iter):\n",
    "            rand_indices = np.random.choice(n_train,batch_size)    \n",
    "            X_batch, y_batch = X_train[rand_indices], y_train[rand_indices]\n",
    "            sess.run(train_operation, feed_dict={X: X_batch, labels: y_batch, training_: True})\n",
    "        acc_train = accuracy.eval(feed_dict={X: X_batch, labels: y_batch})\n",
    "        print(\"Epoch {} training accuracy : {}\".format(epoch, acc_train))\n",
    "        save_path = saver.save(sess, path)\n",
    "        saver.restore(sess, path)\n",
    "    saver.restore(sess, path)\n",
    "    for snr in snrs:\n",
    "        acc_test[snr] = accuracy.eval(feed_dict={X: X_test[snr], labels: y_test[snr]})\n",
    "\n",
    "print(\"Training took %f minutes\"%(float(time() - start)/60.0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Test the classifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CNN's test accuracy on -20dB SNR samples = 0.13075000047683716\n",
      "CNN's test accuracy on -18dB SNR samples = 0.1264999955892563\n",
      "CNN's test accuracy on -16dB SNR samples = 0.12800000607967377\n",
      "CNN's test accuracy on -14dB SNR samples = 0.1392499953508377\n",
      "CNN's test accuracy on -12dB SNR samples = 0.15649999678134918\n",
      "CNN's test accuracy on -10dB SNR samples = 0.1912499964237213\n",
      "CNN's test accuracy on -8dB SNR samples = 0.2549999952316284\n",
      "CNN's test accuracy on -6dB SNR samples = 0.3687500059604645\n",
      "CNN's test accuracy on -4dB SNR samples = 0.49399998784065247\n",
      "CNN's test accuracy on -2dB SNR samples = 0.6167500019073486\n",
      "CNN's test accuracy on 0dB SNR samples = 0.6662499904632568\n",
      "CNN's test accuracy on 2dB SNR samples = 0.6915000081062317\n",
      "CNN's test accuracy on 4dB SNR samples = 0.7124999761581421\n",
      "CNN's test accuracy on 6dB SNR samples = 0.7129999995231628\n",
      "CNN's test accuracy on 8dB SNR samples = 0.722000002861023\n",
      "CNN's test accuracy on 10dB SNR samples = 0.721750020980835\n",
      "CNN's test accuracy on 12dB SNR samples = 0.7135000228881836\n",
      "CNN's test accuracy on 14dB SNR samples = 0.7145000100135803\n",
      "CNN's test accuracy on 16dB SNR samples = 0.715749979019165\n",
      "CNN's test accuracy on 18dB SNR samples = 0.7254999876022339\n"
     ]
    }
   ],
   "source": [
    "for snr in snrs:\n",
    "    print(\"CNN's test accuracy on {}dB SNR samples = {}\".format(snr,acc_test[snr]))  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Visualize classifier's performance on test set"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f67de317438>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.style.use('classic')\n",
    "%matplotlib inline\n",
    "\n",
    "acc_test = sorted(acc_test.items())\n",
    "new_acc = []\n",
    "for i in range(len(acc_test)):\n",
    "    new_acc.append(acc_test[i][1])\n",
    "acc_test_values = new_acc \n",
    "\n",
    "fig1 = plt.figure(figsize=(10, 6), dpi=100)\n",
    "x = snrs\n",
    "y = list(acc_test_values)\n",
    "plt.plot(x, y, marker=\"o\", linewidth=2.0, linestyle='dashed', color='royalblue')\n",
    "plt.axis([-20, 20, 0, 1])\n",
    "plt.xticks(np.arange(min(x), max(x)+1, 2.0))\n",
    "plt.yticks(np.arange(0, 1, 0.10))\n",
    "\n",
    "ttl = plt.title('SNR vs Accuracy', fontsize=16)\n",
    "ttl.set_weight('bold')\n",
    "plt.xlabel('SNR (dB)', fontsize=14)\n",
    "plt.ylabel('Test accuracy', fontsize=14)\n",
    "plt.grid()\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0.1\n",
      "Confusion Matrix\n",
      "       8PSK  BPSK  CPFSK  GFSK  PAM4  QAM16  QAM64  QPSK\n",
      "8PSK   0.55  0.01   0.03  0.00  0.00   0.03   0.03  0.34\n",
      "BPSK   0.00  0.97   0.00  0.00  0.02   0.00   0.00  0.01\n",
      "CPFSK  0.02  0.00   0.92  0.01  0.00   0.01   0.00  0.04\n",
      "GFSK   0.02  0.01   0.01  0.95  0.00   0.00   0.00  0.01\n",
      "PAM4   0.00  0.02   0.00  0.00  0.97   0.01   0.01  0.00\n",
      "QAM16  0.07  0.00   0.00  0.00  0.02   0.44   0.43  0.04\n",
      "QAM64  0.04  0.01   0.00  0.00  0.03   0.42   0.48  0.02\n",
      "QPSK   0.28  0.07   0.01  0.00  0.00   0.05   0.01  0.58\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f67d2f91d30>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Confusion Matrix\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    saver.restore(sess, path)\n",
    "    Z = logits.eval(feed_dict = {X : X_test[18]})\n",
    "    predicted_18dB = np.argmax(Z, axis = 1)\n",
    "    \n",
    "from sklearn.metrics import confusion_matrix\n",
    "%matplotlib inline\n",
    "\n",
    "classes = ['8PSK', 'BPSK', 'CPFSK', 'GFSK', 'PAM4', 'QAM16', 'QAM64', 'QPSK']\n",
    "conf_matrix = confusion_matrix(predicted_18dB, y_test[18])  \n",
    "\n",
    "conf_matrix = conf_matrix.astype('float') / conf_matrix.sum(axis=1)[:, np.newaxis]\n",
    "conf_matrix = conf_matrix.round(decimals = 2)\n",
    "\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame(data = conf_matrix, columns = classes, index = classes) \n",
    "print(\"Confusion Matrix\")\n",
    "print(df)\n",
    "\n",
    "fig1 = plt.figure(figsize=(10, 6), dpi=100)\n",
    "plt.imshow(conf_matrix, interpolation = 'nearest', cmap = plt.cm.Purples)\n",
    "ticks = np.arange(len(classes))\n",
    "plt.title(\"Confusion Matrix\")\n",
    "plt.xticks(ticks, classes, rotation=45)\n",
    "plt.yticks(ticks, classes)\n",
    "\n",
    "plt.ylabel('True class')\n",
    "plt.xlabel('Predicted class')\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.colorbar()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
